package mallshop.tongyi.com.adbhepler.server;

import android.util.Log;

import com.blankj.utilcode.util.CloseUtils;
import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ZipUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipFile;

/**
 * The micro server in Android
 * <p>
 * Created by mayubao on 2016/12/14.
 * Contact me 345269374@qq.com
 */
public class AndroidMicroServer {

    private static final String TAG = AndroidMicroServer.class.getSimpleName();

    /**
     * the server port
     */
    private int mPort = 8888;

    /**
     * the server socket
     */
    private ServerSocket mServerSocket;

    /**
     * the thread pool which handle the incoming request
     */
    private ExecutorService mThreadPool = Executors.newCachedThreadPool();


    /**
     * the flag which the micro server enable
     */
    private boolean mIsEnable = true;


    public AndroidMicroServer(int port) {
        this.mPort = port;
    }


    /**
     * start the android micro server
     */
    public void start() {
        mThreadPool.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    mServerSocket = new ServerSocket(mPort);

                    while (mIsEnable) {
                        Socket socket = mServerSocket.accept();
                        hanlderSocketAsyn(socket);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }


    /**
     * stop the android micro server
     */
    public void stop() {
        if (mIsEnable) {
            mIsEnable = false;
        }

        //release resource

        if (mServerSocket != null) {
            try {
//                mServerSocket.accept(); //fuck ! fix the problem， block the main thread
                mServerSocket.close();
                mServerSocket = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * handle the incoming socket
     *
     * @param socket
     */
    private void hanlderSocketAsyn(final Socket socket) {
        mThreadPool.submit(new Runnable() {
            @Override
            public void run() {
                //1. auto create request object by the parameter socket
                InputStream inputStream = null;
                FileOutputStream fileOutputStream = null;
                OutputStream outputStream = null;
                FileInputStream fileInputStream = null;
                try {
                    inputStream = socket.getInputStream();
                    outputStream = socket.getOutputStream();

                    String header = readHeader(inputStream);
                    if ("pull".equals(header)) {
                        // user want to  pull file to client
                        File file = new File("/sdcard/Download/QQMail");
                        LogUtils.e("压缩要传输的文件");
                        writeFile(file,outputStream);

                    } else {
                        //user want to push file to server

                        String fileName = header;
                        String path = "/sdcard/Download/QQMail/" + fileName;
                        File file = new File(path);
                        if (file.exists()) {
                            file.delete();
                        }
                        writeDataToFile(inputStream, file);
                        LogUtils.e("完成文件写入" + fileName);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {

                    CloseUtils.closeIO(fileOutputStream, fileInputStream);
                    CloseUtils.closeIO(inputStream);
                    CloseUtils.closeIO(outputStream);
                }
            }
        });
    }

    private void writeFile(File file, OutputStream outputStream) throws IOException {
        // TODO: 2019-10-27 远程写入文件夹
        if(file.isDirectory()){
            for (File childFile : file.listFiles()) {
                writeFile(file,outputStream);
            }
        }else{
            writeHeader(file.getName(),outputStream);
        }
    }

    private void  writeDataToFile(InputStream inputStream, File file) throws IOException {
        FileOutputStream fileOutputStream = null;
        fileOutputStream = new FileOutputStream(file);

        int len;
        byte[] cache = new byte[1024 * 5];
        while ((len = inputStream.read(cache)) != -1) {
            fileOutputStream.write(cache, 0, len);
        }

    }

    private String readHeader(InputStream inputStream) throws IOException {
        byte[] headerCache = new byte[512];
        inputStream.read(headerCache, 0, headerCache.length);
        return new String(headerCache, Charset.forName("utf-8")).trim();
    }


    private static void readFileDataToOutStream(FileInputStream fileInputStream, OutputStream outputStream) throws IOException {
        int len;
        byte[] b = new byte[1024 * 5];
        while ((len = fileInputStream.read(b)) != -1) {
            outputStream.write(b, 0, len);
        }
    }


    public  void  writeHeader(String header,OutputStream outputStream) throws IOException {
        byte[] bytes = header.getBytes(Charset.forName("utf-8"));
        byte[] placeHolder = new byte[512 - bytes.length];
        outputStream.write(bytes);
        outputStream.write(placeHolder);

    }


}




